package cn.restcloud.example.controller.rdb;

import java.util.ArrayList;
import java.util.List;
import org.bson.Document;
import cn.restcloud.framework.core.annotation.bean.BeanConfig;
import cn.restcloud.framework.core.annotation.bean.BeanType;
import cn.restcloud.framework.core.annotation.rest.MethodType;
import cn.restcloud.framework.core.annotation.rest.RestConfig;
import cn.restcloud.framework.core.base.IBasePageBean;
import cn.restcloud.framework.core.util.RequestUtil;
import cn.restcloud.framework.core.util.db.rdb.RdbDataModelUtil;
import cn.restcloud.framework.core.util.db.rdb.RdbMapperUtil;
import cn.restcloud.framework.core.util.db.rdb.RdbUtil;
import cn.restcloud.framework.view.base.DocAndView;
import cn.restcloud.framework.view.util.ViewUtil;

/**
 * RestCloud平台访问数据库的工具类一共有三个<br>
 * 1.RdbUtil主要功能是直接使用SQL语句操作任意数据库表<br>
 * 2.RdbMapperUtil与mybatis功能一至主要通过配置SQL然后操作数据库表，RdbMapperUtil与RdbUtil的区别是RdbMapperUtil中不用写死sql语句,sql是在web中配置的,RdbUtil是直接在Java代码中写死的sql语句执行的<br>
 * 3.RdbDataModelUtil的主要功能是直接操作数据模型、业务模型对数据库表进行CRUD操作<br>
 * 建方：优先建立数据模型然后用RdbDataModelUtil操作数据模型，其次使用RdbMapperUtil工具类操作统一配置的SQL，最后自由度最大的RdbUtil工具类操作任意SQL<br>
 * @author Thinkpad
 *
 */
@BeanConfig(appId = "example",beanId = "SqlUtilDemoRest",beanName = "数据库操作工具类使用示例",beanType = BeanType.CONTROLLER,autowired = false,singleton = true,hotMode = true)
@RestConfig(url = "/rest/example/rdb/util")
public class SqlUtilDemoRest {
	//这里有几个方法同样操作数据库中的一个表UserModel表，使用三种不同的工具类进行操作，可以看到他们之间的差别和优势
	
	@RestConfig(configName = "列出多个数据源中的数据进行合并",method = MethodType.GET,url = "/unionall")
	public DocAndView unialAllDatas()throws Exception{
		String sql="select * from userList";
		List<Document> docs_a=RdbUtil.listDocs(RdbUtil.getConnection("数据源A"),sql);
		
		sql="select * from userName";
		List<Document> docs_b=RdbUtil.listDocs(RdbUtil.getConnection("数据源B"),sql);
		
		//进行union all组合
		List<Document> docs_unionall=new ArrayList<Document>();
		docs_unionall.addAll(docs_a);
		docs_unionall.addAll(docs_b);
		
		return ViewUtil.getJsonView(docs_unionall);
	}
	
	@RestConfig(configName = "列出数据模型的所有记录(优)",method = MethodType.GET,url = "/RdbDataModelUtil")
	public DocAndView rdbDataModelUtilDemo()throws Exception{
		String modelId="example.UserModel"; //在应用中对UserModel表建立一个名为example.UserModel实体模型
		List<Document> docs=RdbDataModelUtil.listAll(modelId); //获得此表的所有数据记录
		return ViewUtil.getJsonView(docs);
	}
	
	@RestConfig(configName = "列出UserModel表中的的所有记录(良)",method = MethodType.GET,url = "/RdbMapperUtil")
	public DocAndView rdbMapperUtilDemo()throws Exception{
		String configId="example.UserModel.selectAll"; //在应用中的SQL配置中配置一条sql语句：select * from UserModel;
		List<Document> docs=RdbMapperUtil.selectList(configId);
		return ViewUtil.getJsonView(docs);
	}
	
	@RestConfig(configName = "列出UserModel表中的的所有记录(差)",method = MethodType.GET,url = "/RdbUtil")
	public DocAndView rdbUtilDemo()throws Exception{
		String sql="select * from UserModel"; //直接在java代码中写死sql语句
		List<Document> docs=RdbUtil.listDocs(sql);
		return ViewUtil.getJsonView(docs);
	}
	
	@RestConfig(configName = "插入一条记录到表中(优)",method = MethodType.GET,url = "/RdbDataModelUtil/insert")
	public DocAndView rdbDataModelUtilInsertDemo()throws Exception{
		String modelId="example.UserModel"; //在应用中对UserModel表建立一个名为example.UserModel实体模型
		Document doc=RequestUtil.getContextDocument(); //表单提交过来的所有参数
		int i=RdbDataModelUtil.save(modelId, doc); //通过数据模型自动持久化到UserModel表中
		return ViewUtil.getSuccessView(String.valueOf(i));
	}
	
	@RestConfig(configName = "插入一条记录到表中(差)",method = MethodType.GET,url = "/RdbMapperUtil/insert")
	public DocAndView rdbMapperUtilInsertDemo()throws Exception{
		//需要配置一条insert sql语句，开发效率较低,如果数据库字段修改还需要修改sql语句
		String configId="example.UserModel.insert"; //在应用中的SQL配置中配置一条sql语句：insert into UserModel(userid,username,age)values(#{userid},#{username},#{age});
		Document doc=RequestUtil.getContextDocument(); //表单提交过来的所有参数
		int i=RdbMapperUtil.insert(configId,doc); //自动匹配sql中的参数进行预编译sql执行
		return ViewUtil.getSuccessView(String.valueOf(i));
	}

	@RestConfig(configName = "插入一条记录到表中(良)",method = MethodType.GET,url = "/RdbUtil/save")
	public DocAndView rdbUtilInsertDemo()throws Exception{
		//优点不用建立数据模型，不用配置sql语句
		Document doc=RequestUtil.getContextDocument(); //表单提交过来的所有参数
		int i=RdbUtil.saveDoc("UserModel", doc, "UserId"); //直接指定表名和关键字段的id,系统可以直接生成sql语句进行持久化
		return ViewUtil.getSuccessView(String.valueOf(i));
	}
	

	@RestConfig(configName = "分页查询(优)",method = MethodType.GET,url = "/RdbDataModelUtil/listByPage")
	public DocAndView rdbDataModelUtilPageDemo()throws Exception{
		String modelId="example.UserModel"; //在应用中对UserModel表建立一个名为example.UserModel实体模型
		int pageNo=1,pageSize=20;
		String sqlWhere="age=?";  //缺点java代码中耦合了sql语句的条件
		String orderBy="userId";
		String sortDirection="desc";
		IBasePageBean<Document> pageBean=RdbDataModelUtil.listByPage(modelId, sqlWhere, orderBy, sortDirection, pageNo, pageSize,"15");
		return ViewUtil.getJsonView(pageBean);
	}
	
	@RestConfig(configName = "分页查询(优)",method = MethodType.GET,url = "/RdbMapperUtil/listByPage")
	public DocAndView rdbMapperUtilPageDemo()throws Exception{
		//没有耦合sql语句,sql语句是在sql配置中动态配置的
		String configId="example.UserModel.listByPage"; //在应用中的SQL配置中配置一条动态sql语句：sql="分页的sql语句";countSql="计算总页数的sql";
		int pageNo=1,pageSize=20;
		Document paramDoc=new Document();
		paramDoc.put("age", "15"); //传入参数到sqlWhere条件中的#{age}变量中
		IBasePageBean<Document> pageBean=RdbMapperUtil.selectListByPage(configId, pageNo, pageSize, paramDoc);
		return ViewUtil.getJsonView(pageBean);
	}
	
	@RestConfig(configName = "分页查询(差)",method = MethodType.GET,url = "/RdbUtil/listByPage")
	public DocAndView rdbUtilPageDemo()throws Exception{
		//优点不用建立数据模型，不用配置sql语句
		IBasePageBean<Document> pageBean=RdbUtil.getPageBean(Document.class);
		pageBean.setPageNo(1);
		pageBean.setPageSize(15);
		pageBean.setSqlTableName("UserModel");
		pageBean.setSqlOrderby("order by userId desc");
		pageBean.setSqlFields("*");
		pageBean.setSqlWhere("age=?"); //缺点java代码中耦合了sql语句的条件
		RdbUtil.listDocsByPage(pageBean, "15");
		return ViewUtil.getJsonView(pageBean);
	}
	
}
